macos: lookup NSEvent by translated GdkEvent
authorChristian Hergert <chergert@redhat.com>
Sat, 10 Oct 2020 02:58:07 +0000 (19:58 -0700)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 14 Oct 2020 19:06:12 +0000 (15:06 -0400)
This will be needed by the quartz imcontext.

gdk/macos/gdkmacosdisplay-private.h
gdk/macos/gdkmacosdisplay.c

index a60ab0c6ac708646267d04cfabe7b32e828cf1dd..9f45a2e2009ac70b3c9942420951ba0da71552e6 100644 (file)
@@ -161,6 +161,7 @@ void             _gdk_macos_display_send_button_event              (GdkMacosDisp
 void             _gdk_macos_display_warp_pointer                   (GdkMacosDisplay *self,
                                                                     int              x,
                                                                     int              y);
+NSEvent         *_gdk_macos_display_get_nsevent                    (GdkEvent        *event);
 
 G_END_DECLS
 
index 13d7dc8d1b31ed1401a2eaba616084e5ae85b6b5..8f6a9eb558fcb2b504b99cc6d82108a25a445549 100644 (file)
 
 G_DEFINE_TYPE (GdkMacosDisplay, gdk_macos_display, GDK_TYPE_DISPLAY)
 
+#define EVENT_MAP_MAX_SIZE 10
+
+typedef struct
+{
+  GList     link;
+  GdkEvent *gdk_event;
+  NSEvent  *nsevent;
+} GdkToNSEventMap;
+
 static GSource *event_source;
+static GQueue event_map = G_QUEUE_INIT;
 
 static GdkMacosMonitor *
 get_monitor (GdkMacosDisplay *self,
@@ -387,6 +397,28 @@ gdk_macos_display_notify_startup_complete (GdkDisplay  *display,
   /* Not Supported */
 }
 
+static void
+push_nsevent (GdkEvent *gdk_event,
+              NSEvent  *nsevent)
+{
+  GdkToNSEventMap *map = g_slice_new0 (GdkToNSEventMap);
+
+  map->link.data = map;
+  map->gdk_event = gdk_event_ref (gdk_event);
+  map->nsevent = g_steal_pointer (&nsevent);
+
+  g_queue_push_tail_link (&event_map, &map->link);
+
+  if (event_map.length > EVENT_MAP_MAX_SIZE)
+    {
+      map = g_queue_pop_head_link (&event_map)->data;
+
+      gdk_event_unref (map->gdk_event);
+      [map->nsevent release];
+      g_slice_free (GdkToNSEventMap, map);
+    }
+}
+
 static void
 gdk_macos_display_queue_events (GdkDisplay *display)
 {
@@ -400,14 +432,18 @@ gdk_macos_display_queue_events (GdkDisplay *display)
       GdkEvent *event = _gdk_macos_display_translate (self, nsevent);
 
       if (event != NULL)
-        _gdk_windowing_got_event (GDK_DISPLAY (self),
-                                  _gdk_event_queue_append (GDK_DISPLAY (self), event),
-                                  event,
-                                  0);
+        {
+          push_nsevent (event, nsevent);
+          _gdk_windowing_got_event (GDK_DISPLAY (self),
+                                    _gdk_event_queue_append (GDK_DISPLAY (self), event),
+                                    event,
+                                    0);
+        }
       else
-        [NSApp sendEvent:nsevent];
-
-      [nsevent release];
+        {
+          [NSApp sendEvent:nsevent];
+          [nsevent release];
+        }
     }
 }
 
@@ -1069,3 +1105,17 @@ _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
 
   CGWarpMouseCursorPosition ((CGPoint) { x, y });
 }
+
+NSEvent *
+_gdk_macos_display_get_nsevent (GdkEvent *event)
+{
+  for (const GList *iter = event_map.head; iter; iter = iter->next)
+    {
+      const GdkToNSEventMap *map = iter->data;
+
+      if (map->gdk_event == event)
+        return map->nsevent;
+    }
+
+  return NULL;
+}